   This file documents ph.el v2.6

   ph.el is part of GNU Emacs.

   ph.el is an E-Lisp client interface to the CCSO white pages
directory system also known as PH/QI

   Copyright (C) 1997 Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying and the terms of
the "GNU General Public License", and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Free Software Foundation.

   This manual documents ph.el v2.6, an E-lisp client interface to the
CCSO PH/QI directory system.

Introduction
************

   The Central Computing Services Office (CCSO) of the University of
Illinois at Urbana Champaign (UIUC) created and freely distributes a
directory system that is currently in use in more than 300 organizations
around the world. The system records information about people such as
their address, phone number, e-mail, academic information or any other
details it was configured to.

   The system consists of two parts: a database server traditionally
called `qi' and a command-line client called `ph'.
`ftp://uiarchive.cso.uiuc.edu/pub/packages/ph' is the main distribution
site.  `http://www.uiuc.edu/cgi-bin/ph/lookup?Query=.' provides a
listing of the QI servers in activity.

   `ph.el' provides a client interface to this directory system letting
you:

   * query the server through a customizable form

   * expand inline queries in buffers (for instance you can expand a
     name to a mailing address in a mail message buffer)

   * insert server records into your own BBDB database (see BBDB (bbdb))

   The original command-line `ph' client that comes with the `ph/qi'
distribution provides additional features like the possibility to
communicate with the server in login mode which makes it possible to
change records in the database. This is not implemented in this e-lisp
client.

Installation
************

   If you are using `ph' from your GNU Emacs or XEmacs distribution you
can skip this section.

   `ph' should work right out of the box with XEmacs 19.15 and above.
It will not work with versions of XEmacs below.

   `ph' will work with Emacs 19.34 provided you have the `custom' and
`widget' libraries by Per Abrahmsen installed. You can get them from
`http://www.dina.kvl.dk/~abraham/custom/'

   When installing `ph' yourself you should move `ph.el' to a proper
directory in your `load-path' and byte-compile it (see the section on
byte-compilation in your users manual if you do not know what that
means). Install `ph.info' into a directory where the info system can
find it or update your `Info-default-directory-list' variable.

   Then you can add the following into your `.emacs' startup file:
     (require 'ph)
     (eval-after-load
      "message"
      '(define-key message-mode-map [(control ?c) (tab)] 'ph-expand-inline))
     (eval-after-load
      "mail"
      '(define-key mail-mode-map [(control ?c) (tab)] 'ph-expand-inline))

   Upon starting a new session you will find a new `Ph' sub-menu in the
`Tools' menu that will let you access all the interesting `ph'
functions.

Usage
*****

   This chapter describes the usage of `ph.el'. Most functions are
available through the `Ph' sub-menu of the `Tools' sub-menu.

Querying Servers
================

   `ph' basic functionality is to let you query a QI server and return
the results back to you. There are several things you may want to
customize in this process.

Selecting a Server
------------------

   Before doing any query you will need to set the query server, this is
the name of the host machine running the `qi' software. If you do not
set it in any fashion, `ph' will ask you for one when you make your
first query.

 - Variable: ph-server
     The name or IP address of the CCSO (PH/QI) server. A port number
     may be specified by appending a colon and a number to the name of
     the server. You will not need this unless your server runs on
     different port than the usual 105.

Return Fields
-------------

   `qi' servers are configured to return a default set of fields for
each record matching a query if the query specifies none. The variable
`ph-default-return-fields' controls the return fields you want for your
queries.

 - Variable: ph-default-return-fields
     A list of the default fields to extract from CCSO entries.  If it
     contains `all' then all available fields are returned. `nil' means
     return the default fields as configured in the server. Default is
     `nil'

   The server may return several matching records to a query. Some of
the records may however not contain all the fields you requested. You
can chose to discard those records.

 - User Option: ph-strict-return-matches
     If non-`nil', entries that do not contain all the requested return
     fields are ignored.  Default is `t'.

Handling Duplicate Fields
-------------------------

   `qi' authorizes records to have different instances of the same
field. For instance the record of a person may contain several e-mail
fields containing different e-mail addresses. This is difficult to
distinguish from fields having multi-line values such as the postal
address that may contain a line for the street and another one for the
zip code and city name. In both cases, `ph' considers the field be
duplicated.

   `ph' has several methods to deal with duplicate fields. The
available methods are:

`list'
     Makes a list with the different values of the duplicate field. The
     record keeps only one instance of the field the value of which is
     a list of all the different values. This is the default method
     that is used to handle duplicate fields for which no other method
     has been specified.

`first'
     Discards all the duplicate values of the field keeping only the
     first one.

`concat'
     Concatenates the different values using `\n' as a separator. The
     record keeps only one instance of the field the value of which is a
     single multi-line string.

`duplicate'
     Duplicates the whole record into as many instances as there are
     different values for the field. This is the default for the e-mail
     field. Thus a record containing 3 different e-mail addresses is
     duplicated into three different records each having a single
     e-mail address. This is particularly useful in combination with
     `select' as the method to handle multiple matches in inline
     expansion queries (see Inline Query Expansion.) because you
     are presented with the 3 addresses in a selection buffer

   Because a method may not be applicable to all fields, the variable
`ph-duplicate-fields-handling-method' lets you specify either a default
method for all fields or a method for each individual field.

 - Variable: ph-duplicate-fields-handling-method
     A method to handle entries containing duplicate fields.  This is
     either an alist (FIELD . METHOD) or a symbol METHOD.  The alist
     form of the variable associates a method to an individual field,
     the second form specifies a method applicable to all fields.
     Available methods are: `list', `first', `concat', `duplicate'
     duplicates the entire entry into as many instances as different
     values.  Defaults to `list'.

Query Form
==========

   The simplest way to query your directory server is to use the query
form. You display the query form with the `Query Form' menu item or by
typing `M-x ph-query-form'. The fields presented in this form are
defined by the `ph-form-fields' variable (unless a non-`nil' argument
is supplied to `ph-query-form').

 - Variable: ph-form-fields
     A list of fields presented in the query form. You can get a list of
     valid field names with the `List Valid Field Names' menu item or
     `M-x ph-get-field-list'. Defaults to `name', `email' and `phone'.

 - Command: ph-query-form GET-FIELDS-FROM-SERVER
     Display a form to query the CCSO PH/QI Nameserver.  If given a
     non-nil argument the function first queries the  server for the
     existing fields and displays a corresponding form.

   Since the names of the fields may not be explicit enough or adapted
to be directly displayed as prompt strings in the form, the variable
`ph-fieldname-formstring-alist' lets you define prompt strings for the
various fields.

 - Variable: ph-fieldname-formstring-alist
     This is an alist mapping CCSO database field names onto prompt
     strings used in query/response forms. Prompt strings for fields
     that are not in this alist are derived by replacing underscores
     with spaces and capitalizing the individual words.

   Upon successful completion the command will display a buffer
containing the results of the query. The fields that are returned for
each record are controlled by `ph-default-return-fields' (see Return Fields.)

Inline Query Expansion
======================

   Instead of using a query form, you may prefer inline expansion. This
is a powerful method to get completion from your directory server. The
most common usage is for expanding names to e-mail addresses in mail
message buffers. The expansion is performed by the command
`ph-expand-inline'. The operation is controlled by the variables
`ph-inline-expansion-format', `ph-inline-query-format-list',
`ph-expanding-overwrites-query' and `ph-multiple-match-handling-method'

 - Command: ph-expand-inline REPLACE-P
     Query the server and expand the query string before point.  The
     query string consists of the buffer substring from the point back
     to the preceding comma, colon or beginning of line. If it consists
     of more than one word the variable `ph-inline-query-format-list'
     controls how these are mapped onto CCSO database field names.
     After querying the server for the given string, the expansion
     specified by `ph-inline-expansion-format' is inserted in the
     buffer at point. If REPLACE-P is `t' then this expansion replaces
     the query string in the buffer.  If
     `ph-expanding-overwrites-query' is non-`nil' then the meaning of
     REPLACE-P is negated.

 - Variable: ph-inline-query-format-list
     Format of an inline expansion query.  If the inline query string
     consists of several words, this list specifies how these individual
     words are associated to CCSO database field names.  If `nil' all
     the words will be mapped onto the default CCSO database key
     (generally `name'). Default is `nil'.

 - Variable: ph-inline-expansion-format
     This variable lets you control what is exactly inserted into the
     buffer upon an inline expansion request. It is a list whose first
     element is a string passed to `format'. Remaining elements are
     symbols corresponding to CCSO database field names, corresponding
     field values are passed as additional arguments to format. Default
     is `("%s" email)' but you may want to consider a value like `("%s
     <%s>" name email)'

 - Variable: ph-multiple-match-handling-method
     This variable controls what to do when multiple entries match a
     query for an inline expansion.  Possible values are:
    `first'
          The first match is considered as being the only one, the
          others are discarded.

    `select'
          A selection buffer pops-up where you can choose a particular
          match. This is the default value of the variable.

    `all'
          The expansion uses all records successively

    `abort'
          An error is signaled. The expansion aborts.

     Defaults to `select'

Creating BBDB Records
=====================

   With `ph', you can automatically create BBDB records (see BBDB (bbdb))
from records you get from a PH/QI server. You do this by
moving the point to the appropriate record in a query result display
buffer and invoking the command `ph-insert-record-at-point-into-bbdb'
with the corresponding keyboard binding, `b' (1) or with the menu. `ph'
cannot update an existing BBDB record and will signal an error if you
try to insert a record matching an existing one.

   Because the CCSO directory system does not enforce a strict record
format, local installations of the QI server use different names for the
record fields and have different ways to organize the information.
Furthermore BBDB has its own record structure that has little to do
with what is commonly found on QI servers. For these reasons the
process of converting a record from its QI format to the BBDB format is
highly customizable.

 - Variable: ph-bbdb-conversion-alist
     This is the variable that lets you customize how BBDB fields map to
     PH/QI records. Its value is an alist of cells of the form
     `('BBDB-FIELD . SPEC-OR-LIST`)'. BBDB-FIELD is the name of a field
     that must be defined in your BBDB environment (standard field
     names are `name', `company', `net', `phone', `address' and
     `notes'). SPEC-OR-LIST is either a single mapping specification or
     a list of mapping specifications. Lists of mapping specifications
     are valid for the `phone' and `address' BBDB fields only. SPECs
     are actually s-expressions which are evaluated as follows:

    a string
          evaluates to itself

    a symbol
          evaluates to the symbol value. Symbols corresponding to PH/QI
          fields present in the record evaluate to the value of the
          field in the record

    a form
          is evaluated as a function. The argument list may contain
          PH/QI field names which evaluate to the corresponding values
          in the record. The form evaluation should return something
          appropriate for the particular BBDB-FIELD (see
          `bbdb-create-internal').  `ph-bbdbify-phone' and
          `ph-bbdbify-address' are provided as convenience functions to
          parse phones and addresses.

   The default value of `ph-bbdb-conversion-alist' is:

     ((name . name)
      (net . email)
      (address . (ph-bbdbify-address address "Address"))
      (phone . ((ph-bbdbify-phone phone "Phone")
                (ph-bbdbify-phone office_phone "Office Phone"))))

   This means that:

   * the `name' field of the BBDB record gets its value from the `name'
     field of the PH/QI record

   * the `net' field of the BBDB record gets its value from the `email'
     field of the PH/QI record

   * the `address' field of the BBDB record is obtained by parsing the
     `address' field of the PH/QI record with the function
     `ph-bbdbify-address'

   * two `phone' fields are created (when possible) in the BBDB record.
     The first one has "Phone" for location and its value is obtained by
     parsing the `phone' field of the PH/QI record with the function
     `ph-bbdbify-phone'. The second one has "Office Phone" for location
     its value is obtained by parsing the `office_phone' field of the
     PH/QI record with the function `ph-bbdbify-phone'.

 - Function: ph-bbdbify-phone PHONE LOCATION
     This is a convenience function provided for use in
     `ph-bbdb-conversion-alist'. It parses PHONE into a vector
     compatible with `bbdb-create-internal'. PHONE is either a string
     supposedly containing a phone number or a list of such strings
     which are concatenated. LOCATION is used as the phone location for
     BBDB.

 - Function: ph-bbdbify-address ADDR LOCATION
     This is a convenience function provided for use in
     `ph-bbdb-conversion-alist'. It parses ADDR into a vector
     compatible with `bbdb-create-internal'. ADDR should be an address
     string of no more than four lines or a list of lines. The last
     line is searched for the zip code, city and state name. LOCATION
     is used as the phone location for BBDB.

   Note that only a subset of the fields you selected with
`ph-default-return-fields' and that are actually displayed may actually
be inserted as part of the newly created BBDB record.

   ---------- Footnotes ----------

   (1) This keybinding does not actually call
`ph-insert-record-at-point-into-bbdb' but uses `ph-try-bbdb-insert'
instead.

The Server Hotlist
==================

   `ph' lets you maintain a list of frequently used servers so that you
can easily switch from one to another. This hotlist appears in the
`Server' sub-menu. You select a server in this list by clicking on its
name. You can add the current server to the list with the command
`ph-bookmark-current-server'. The list is contained in the variable
`ph-server-hotlist' which is stored in and retrieved from the file
designated by `ph-options-file'.

 - Command: ph-bookmark-server SERVER
     Add SERVER to the hotlist of servers

 - Command: ph-bookmark-current-server
     Add the current server to the hotlist of servers

 - Variable: ph-options-file
     The name of a file where `ph' stores its internal variables
     (currently only the hotlist is stored there). `ph' will try to load
     that file upon initialization so, if you choose a file name
     different from the defaults `~/.ph-options', be sure to set this
     variable to the appropriate value *before* `ph' is itself loaded.

   There is currently no way to remove a server from the list other than
editing directly the `ph-options-file'.

Credits
*******

   The original CCSO Nameserver software (`ph' & `qi') was written at
the University of Illinois at Urbana Champaign.

   The Emacs client `ph.el' was written and is maintained by Oscar
Figueiredo.

   Thanks to Soren Dayton for his suggestions, his enthusiasm and his
help in testing and proofreading the code and docs.